using System;
using System.Collections.Generic;
using System.Device.Location;
using System.Linq;
using System.Windows;
using System.Windows.Media.Animation;
namespace Microsoft.Phone.Controls.Maps.Core
{
	public abstract class FlatMapMode : MapMode
	{
		internal struct FlatMapModeViewportDefinition
		{
			private bool isCalculated;
			private Size logicalAreaSizeInScreenSpaceAtLevel1;
			private Size pixelSize;
			private Point topLeftLogicalPoint;
			private double zoomLevelMinusOne;
			public Size LogicalAreaSizeInScreenSpaceAtLevel1
			{
				get
				{
					return this.logicalAreaSizeInScreenSpaceAtLevel1;
				}
				set
				{
					this.logicalAreaSizeInScreenSpaceAtLevel1 = value;
					this.isCalculated = false;
				}
			}
			public double ZoomLevel
			{
				get
				{
					return this.zoomLevelMinusOne + 1.0;
				}
				set
				{
					this.zoomLevelMinusOne = value - 1.0;
					this.isCalculated = false;
				}
			}
			public Point TopLeftLogicalPoint
			{
				get
				{
					return this.topLeftLogicalPoint;
				}
				set
				{
					this.topLeftLogicalPoint = value;
				}
			}
			public void SetTopLeftLogicalPoint(Point focusViewportPoint, Point focusLogicalPoint)
			{
				this.Recalculate();
				this.topLeftLogicalPoint = new Point(focusLogicalPoint.get_X() - focusViewportPoint.get_X() * this.pixelSize.get_Width(), focusLogicalPoint.get_Y() - focusViewportPoint.get_Y() * this.pixelSize.get_Height());
			}
			public Point ViewportPointToLogicalPoint(Point viewportPoint)
			{
				this.Recalculate();
				return new Point(this.topLeftLogicalPoint.get_X() + viewportPoint.get_X() * this.pixelSize.get_Width(), this.topLeftLogicalPoint.get_Y() + viewportPoint.get_Y() * this.pixelSize.get_Height());
			}
			public Point LogicalPointToViewportPoint(Point logicalPoint)
			{
				this.Recalculate();
				return new Point((logicalPoint.get_X() - this.topLeftLogicalPoint.get_X()) / this.pixelSize.get_Width(), (logicalPoint.get_Y() - this.topLeftLogicalPoint.get_Y()) / this.pixelSize.get_Height());
			}
			private void Recalculate()
			{
				if (!this.isCalculated)
				{
					double num = Math.Pow(2.0, this.zoomLevelMinusOne);
					this.pixelSize.set_Width(1.0 / (this.logicalAreaSizeInScreenSpaceAtLevel1.get_Width() * num));
					this.pixelSize.set_Height(1.0 / (this.logicalAreaSizeInScreenSpaceAtLevel1.get_Height() * num));
					this.isCalculated = true;
				}
			}
		}
		private const double AnimationSnap = 0.0005;
		private const double AnimationExtensionRate = 0.1;
		private const double ZoomLevelSlowdownRangeForPan = 2.0;
		private const double KeyCountWeightCoefficientForAnimationDuration = 10.0;
		private const double SignificantZoomLevelChange = 0.5;
		private static readonly TimeSpan InitialAnimationProgress = new TimeSpan(0, 0, 0, 0, (int)Math.Round(16.666666666666668));
		private static readonly TimeSpan BaseAnimaitonDuration = new TimeSpan(0, 0, 0, 0, 1600);
		private static readonly double AnimationSpringWindup = Math.Log(2000.0, 2.7182818284590451);
		private static double ZoomDeltaThresholdToSkipAnimation = 0.5;
		private readonly Storyboard animationStoryboard;
		private readonly List<FlatMapMode.FlatMapModeViewportDefinition> keyDefinitions = new List<FlatMapMode.FlatMapModeViewportDefinition>();
		private TimeSpan animationDuration;
		private DateTime animationStart;
		private FlatMapMode.FlatMapModeViewportDefinition currentViewportDefinition;
		private Size lastViewportSize;
		private Size logicalAreaSizeInScreenSpaceAtLevel1;
		private double nextKeyZoomLevel;
		private FlatMapMode.FlatMapModeViewportDefinition targetViewportDefinition;
		public override GeoCoordinate Center
		{
			get
			{
				Point viewportPoint = new Point(base.ViewportSize.get_Width() / 2.0, base.ViewportSize.get_Height() / 2.0);
				return this.ViewportPointToLocation(viewportPoint, this.currentViewportDefinition);
			}
			set
			{
				double targetZoomLevel = this.TargetZoomLevel;
				double targetHeading = this.TargetHeading;
				double targetPitch = this.TargetPitch;
				this.ConstrainView(value, ref targetZoomLevel, ref targetHeading, ref targetPitch);
				FlatMapMode.FlatMapModeViewportDefinition newView = this.ViewToDefinition(value, targetZoomLevel);
				this.SetView(newView, this.DoAnimation);
			}
		}
		public override GeoCoordinate TargetCenter
		{
			get
			{
				Point viewportPoint = new Point(base.ViewportSize.get_Width() / 2.0, base.ViewportSize.get_Height() / 2.0);
				return this.ViewportPointToLocation(viewportPoint, this.targetViewportDefinition);
			}
		}
		public override double ZoomLevel
		{
			get
			{
				return this.currentViewportDefinition.ZoomLevel;
			}
			set
			{
				GeoCoordinate targetCenter = this.TargetCenter;
				double zoomLevel = value;
				double targetHeading = this.TargetHeading;
				double targetPitch = this.TargetPitch;
				this.ConstrainView(targetCenter, ref zoomLevel, ref targetHeading, ref targetPitch);
				FlatMapMode.FlatMapModeViewportDefinition newView = this.ViewToDefinition(targetCenter, zoomLevel);
				this.SetView(newView, this.DoAnimation);
			}
		}
		public override double TargetZoomLevel
		{
			get
			{
				return this.targetViewportDefinition.ZoomLevel;
			}
		}
		internal FlatMapMode.FlatMapModeViewportDefinition CurrentViewportDefinition
		{
			get
			{
				return this.currentViewportDefinition;
			}
		}
		internal FlatMapMode.FlatMapModeViewportDefinition TargetViewportDefinition
		{
			get
			{
				return this.targetViewportDefinition;
			}
		}
		private bool DoAnimation
		{
			get
			{
				return base.AnimationLevel == AnimationLevel.Full;
			}
		}
		private bool DoUserInputAnimation
		{
			get
			{
				return base.AnimationLevel != AnimationLevel.None;
			}
		}
		protected FlatMapMode(Size logicalAreaSizeInScreenSpaceAtLevel1)
		{
			this.logicalAreaSizeInScreenSpaceAtLevel1 = logicalAreaSizeInScreenSpaceAtLevel1;
			this.currentViewportDefinition.LogicalAreaSizeInScreenSpaceAtLevel1 = logicalAreaSizeInScreenSpaceAtLevel1;
			this.targetViewportDefinition.LogicalAreaSizeInScreenSpaceAtLevel1 = logicalAreaSizeInScreenSpaceAtLevel1;
			this.animationStoryboard = new Storyboard();
			this.animationStoryboard.set_Duration(new Duration(new TimeSpan(0L)));
			this.animationStoryboard.add_Completed(new EventHandler(this.AnimationTick));
		}
		public Point ViewportPointToLogicalPoint(Point viewportPoint)
		{
			return this.currentViewportDefinition.ViewportPointToLogicalPoint(viewportPoint);
		}
		public Point LogicalPointToViewportPoint(Point logicalPoint)
		{
			return this.currentViewportDefinition.LogicalPointToViewportPoint(logicalPoint);
		}
		protected abstract Point LocationToLogicalPoint(GeoCoordinate location);
		public virtual IEnumerable<Point> LocationToLogicalPoint(IEnumerable<GeoCoordinate> locations)
		{
			return Enumerable.Select<GeoCoordinate, Point>(locations, (GeoCoordinate location) => this.LocationToLogicalPoint(location));
		}
		public virtual Rect LocationRectToLogicalRect(LocationRect boundingRectangle)
		{
			Point point = this.LocationToLogicalPoint(boundingRectangle.Northwest);
			Point point2 = this.LocationToLogicalPoint(boundingRectangle.Southeast);
			return new Rect(point, point2);
		}
		protected abstract GeoCoordinate LogicalPointToLocation(Point logicalPoint);
		public virtual bool ConstrainView(GeoCoordinate center, ref double zoomLevel, ref double heading, ref double pitch)
		{
			return false;
		}
		private void ConstrainView(ref FlatMapMode.FlatMapModeViewportDefinition viewportDefinition)
		{
			GeoCoordinate center;
			double zoomLevel;
			this.DefinitionToView(viewportDefinition, out center, out zoomLevel);
			double num = 0.0;
			double num2 = 0.0;
			this.ConstrainView(center, ref zoomLevel, ref num, ref num2);
			viewportDefinition = this.ViewToDefinition(center, zoomLevel);
		}
		public override void OnMapDrag(MapDragEventArgs e)
		{
			Point viewportPoint = new Point(-e.DragDelta.get_X(), -e.DragDelta.get_Y());
			Point point = new Point(e.ViewportPoint.get_X() + e.DragDelta.get_X(), e.ViewportPoint.get_Y() + e.DragDelta.get_Y());
			this.currentViewportDefinition.TopLeftLogicalPoint = this.currentViewportDefinition.ViewportPointToLogicalPoint(viewportPoint);
			this.ConstrainView(ref this.currentViewportDefinition);
			double num = this.nextKeyZoomLevel - this.currentViewportDefinition.ZoomLevel;
			if (this.keyDefinitions.get_Count() > 2 || Math.Abs(num) > 2.0)
			{
				this.keyDefinitions.Clear();
				this.keyDefinitions.Add(this.currentViewportDefinition);
				FlatMapMode.FlatMapModeViewportDefinition flatMapModeViewportDefinition = this.currentViewportDefinition;
				flatMapModeViewportDefinition.ZoomLevel = Math.Round(this.currentViewportDefinition.ZoomLevel + (double)Math.Sign(num) * Math.Min(Math.Abs(num), 2.0));
				this.ConstrainView(ref flatMapModeViewportDefinition);
				this.keyDefinitions.Add(flatMapModeViewportDefinition);
				this.animationDuration = FlatMapMode.BaseAnimaitonDuration;
				this.animationStart = DateTime.get_Now() - FlatMapMode.InitialAnimationProgress;
				this.animationStoryboard.Begin();
			}
			for (int i = 0; i < this.keyDefinitions.get_Count(); i++)
			{
				FlatMapMode.FlatMapModeViewportDefinition flatMapModeViewportDefinition2 = this.keyDefinitions.get_Item(i);
				flatMapModeViewportDefinition2.SetTopLeftLogicalPoint(point, this.currentViewportDefinition.ViewportPointToLogicalPoint(point));
				this.keyDefinitions.set_Item(i, flatMapModeViewportDefinition2);
			}
			this.targetViewportDefinition = this.keyDefinitions.get_Item(this.keyDefinitions.get_Count() - 1);
			this.OnTargetViewChanged();
			this.OnProjectionChanged(ProjectionUpdateLevel.Linear);
			e.Handled = true;
		}
		public override void OnMapFlick(MapFlickEventArgs e)
		{
			Point velocity = e.Velocity;
			double angle = (double)PhysicsHelper.GetAngleFromVelocity(velocity);
			double num = Math.Sqrt(velocity.get_X() * velocity.get_X() + velocity.get_Y() * velocity.get_Y());
			if (num > 1.0)
			{
				num = Math.Min(num, Math.Abs(base.ViewportSize.get_Width() / 2.0));
				num = Math.Min(num, Math.Abs(base.ViewportSize.get_Height() / 2.0));
				velocity = new Point(num * Math.Cos(PhysicsHelper.DegreeToRadian(angle)), num * Math.Sin(PhysicsHelper.DegreeToRadian(angle)));
				FlatMapMode.FlatMapModeViewportDefinition newView = this.currentViewportDefinition;
				newView.SetTopLeftLogicalPoint(velocity, this.currentViewportDefinition.TopLeftLogicalPoint);
				if (this.targetViewportDefinition.ZoomLevel != this.currentViewportDefinition.ZoomLevel)
				{
					newView.ZoomLevel = Math.Round(newView.ZoomLevel);
				}
				this.ConstrainView(ref newView);
				this.SetView(newView, this.DoUserInputAnimation);
			}
			e.Handled = true;
		}
		public override void OnMapZoom(MapZoomEventArgs e)
		{
			bool animate = this.DoUserInputAnimation;
			FlatMapMode.FlatMapModeViewportDefinition newView = this.currentViewportDefinition;
			newView.ZoomLevel += e.ZoomDelta;
			this.ConstrainView(ref newView);
			if (Math.Abs(e.ZoomDelta) < FlatMapMode.ZoomDeltaThresholdToSkipAnimation)
			{
				animate = false;
			}
			else
			{
				newView.ZoomLevel = Math.Round(newView.ZoomLevel);
			}
			newView.SetTopLeftLogicalPoint(e.ViewportPoint, this.currentViewportDefinition.ViewportPointToLogicalPoint(e.ViewportPoint));
			this.ConstrainView(ref newView);
			this.SetView(newView, animate);
			e.Handled = true;
		}
		public override void SetView(GeoCoordinate center, double zoomLevel, double heading, double pitch, bool animate)
		{
			this.ConstrainView(center, ref zoomLevel, ref heading, ref pitch);
			base.Heading = heading;
			base.Pitch = pitch;
			FlatMapMode.FlatMapModeViewportDefinition newView = this.ViewToDefinition(center, zoomLevel);
			this.SetView(newView, animate);
		}
		public override void SetView(LocationRect boundingRectangle, bool animate)
		{
			Rect rect = this.LocationRectToLogicalRect(boundingRectangle);
			FlatMapMode.FlatMapModeViewportDefinition definitionByBounds = this.GetDefinitionByBounds(new Point[]
			{
				new Point(rect.get_Left(), rect.get_Top()),
				new Point(rect.get_Right(), rect.get_Bottom())
			});
			GeoCoordinate center;
			double zoomLevel;
			this.DefinitionToView(definitionByBounds, out center, out zoomLevel);
			this.SetView(center, zoomLevel, this.TargetHeading, this.TargetPitch, animate);
		}
		private void SetView(FlatMapMode.FlatMapModeViewportDefinition newView, bool animate)
		{
			this.lastViewportSize = base.ViewportSize;
			this.targetViewportDefinition = newView;
			this.keyDefinitions.Clear();
			this.keyDefinitions.Add(newView);
			if (!animate)
			{
				this.SnapToTarget();
			}
			else
			{
				this.keyDefinitions.Insert(0, this.currentViewportDefinition);
				Point viewportPoint = new Point(base.ViewportSize.get_Width() / 2.0, base.ViewportSize.get_Height() / 2.0);
				FlatMapMode.FlatMapModeViewportDefinition definitionByBounds = this.GetDefinitionByBounds(new Point[]
				{
					this.keyDefinitions.get_Item(0).ViewportPointToLogicalPoint(viewportPoint),
					this.keyDefinitions.get_Item(1).ViewportPointToLogicalPoint(viewportPoint)
				});
				if (definitionByBounds.ZoomLevel < this.keyDefinitions.get_Item(0).ZoomLevel && definitionByBounds.ZoomLevel < this.keyDefinitions.get_Item(this.keyDefinitions.get_Count() - 1).ZoomLevel)
				{
					this.keyDefinitions.Insert(1, definitionByBounds);
				}
				double num = (double)(this.keyDefinitions.get_Count() - 2) * 10.0;
				for (int i = 0; i < this.keyDefinitions.get_Count() - 1; i++)
				{
					num += Math.Max(Math.Abs(this.keyDefinitions.get_Item(i + 1).ZoomLevel - this.keyDefinitions.get_Item(i).ZoomLevel), 1.0);
				}
				this.animationDuration = new TimeSpan(FlatMapMode.BaseAnimaitonDuration.get_Ticks() * (long)(0.1 * num + 0.9));
				this.animationStart = DateTime.get_Now() - FlatMapMode.InitialAnimationProgress;
				this.animationStoryboard.Begin();
			}
			this.OnTargetViewChanged();
		}
		public override void ViewportSizeChanged(Size viewportSize)
		{
			base.ViewportSizeChanged(viewportSize);
			if (this.lastViewportSize != base.ViewportSize)
			{
				Point viewportPoint = new Point((this.lastViewportSize.get_Width() - base.ViewportSize.get_Width()) / 2.0, (this.lastViewportSize.get_Height() - base.ViewportSize.get_Height()) / 2.0);
				this.currentViewportDefinition.TopLeftLogicalPoint = this.currentViewportDefinition.ViewportPointToLogicalPoint(viewportPoint);
				for (int i = 0; i < this.keyDefinitions.get_Count(); i++)
				{
					FlatMapMode.FlatMapModeViewportDefinition flatMapModeViewportDefinition = this.keyDefinitions.get_Item(i);
					flatMapModeViewportDefinition.TopLeftLogicalPoint = flatMapModeViewportDefinition.ViewportPointToLogicalPoint(viewportPoint);
					this.keyDefinitions.set_Item(i, flatMapModeViewportDefinition);
				}
				if (this.keyDefinitions.get_Count() > 0)
				{
					this.targetViewportDefinition = this.keyDefinitions.get_Item(this.keyDefinitions.get_Count() - 1);
				}
				else
				{
					this.targetViewportDefinition = this.currentViewportDefinition;
				}
				this.lastViewportSize = base.ViewportSize;
				this.OnProjectionChanged(ProjectionUpdateLevel.Linear);
			}
		}
		public override GeoCoordinate ViewportPointToLocation(Point viewportPoint)
		{
			GeoCoordinate result;
			if (!this.TryViewportPointToLocation(viewportPoint, out result))
			{
				throw new ArgumentException(ExceptionStrings.ViewportPointToLocation_DefaultException);
			}
			return result;
		}
		public override bool TryViewportPointToLocation(Point viewportPoint, out GeoCoordinate location)
		{
			location = this.ViewportPointToLocation(viewportPoint, this.currentViewportDefinition);
			return true;
		}
		public override Point LocationToViewportPoint(GeoCoordinate location)
		{
			Point result;
			if (!this.TryLocationToViewportPoint(location, out result))
			{
				throw new ArgumentException(ExceptionStrings.LocationToViewportPoint_DefaultException);
			}
			return result;
		}
		public override bool TryLocationToViewportPoint(GeoCoordinate location, out Point viewportPoint)
		{
			viewportPoint = this.LocationToViewportPoint(location, this.currentViewportDefinition);
			return true;
		}
		public override IEnumerable<Point> LocationToViewportPoint(IEnumerable<GeoCoordinate> locations)
		{
			return Enumerable.Select<GeoCoordinate, Point>(locations, (GeoCoordinate location) => this.LocationToViewportPoint(location, this.currentViewportDefinition));
		}
		public override Rect LocationToViewportPoint(LocationRect boundingRectangle)
		{
			return this.LocationToViewportPoint(boundingRectangle, this.currentViewportDefinition);
		}
		internal GeoCoordinate ViewportPointToLocation(Point viewportPoint, FlatMapMode.FlatMapModeViewportDefinition definition)
		{
			Point logicalPoint = definition.ViewportPointToLogicalPoint(viewportPoint);
			return this.LogicalPointToLocation(logicalPoint);
		}
		internal Point LocationToViewportPoint(GeoCoordinate location, FlatMapMode.FlatMapModeViewportDefinition definition)
		{
			Point logicalPoint = this.LocationToLogicalPoint(location);
			return definition.LogicalPointToViewportPoint(logicalPoint);
		}
		internal Rect LocationToViewportPoint(LocationRect boundingRectangle, FlatMapMode.FlatMapModeViewportDefinition definition)
		{
			Rect rect = this.LocationRectToLogicalRect(boundingRectangle);
			Point point = definition.LogicalPointToViewportPoint(new Point(rect.get_Left(), rect.get_Top()));
			Point point2 = definition.LogicalPointToViewportPoint(new Point(rect.get_Right(), rect.get_Bottom()));
			return new Rect(point, point2);
		}
		private void SnapToTarget()
		{
			this.animationStart = DateTime.MinValue;
			this.animationStoryboard.Stop();
			bool flag = this.currentViewportDefinition.ZoomLevel != this.targetViewportDefinition.ZoomLevel;
			this.currentViewportDefinition = this.targetViewportDefinition;
			this.nextKeyZoomLevel = this.currentViewportDefinition.ZoomLevel;
			this.OnProjectionChanged(flag ? ProjectionUpdateLevel.Full : ProjectionUpdateLevel.Linear);
		}
		private void AnimationTick(object sender, EventArgs e)
		{
			double num = (DateTime.get_Now() - this.animationStart).get_TotalSeconds() / this.animationDuration.get_TotalSeconds();
			if (num < 1.0 && this.keyDefinitions.get_Count() >= 1)
			{
				double num2 = (1.0 - Math.Exp(-num * FlatMapMode.AnimationSpringWindup)) / 0.9995;
				int num3 = 0;
				double num4 = 0.0;
				double num5 = 0.0;
				for (int i = 0; i < this.keyDefinitions.get_Count() - 1; i++)
				{
					num5 += Math.Max(Math.Abs(this.keyDefinitions.get_Item(i + 1).ZoomLevel - this.keyDefinitions.get_Item(i).ZoomLevel), 1.0);
				}
				double num6 = num2 * num5;
				double num7 = 0.0;
				for (int j = 0; j < this.keyDefinitions.get_Count() - 1; j++)
				{
					double num8 = Math.Max(Math.Abs(this.keyDefinitions.get_Item(j + 1).ZoomLevel - this.keyDefinitions.get_Item(j).ZoomLevel), 1.0);
					if (num7 + num8 > num6)
					{
						num3 = j;
						num4 = (num6 - num7) / num8;
						IL_171:
						double num9 = this.keyDefinitions.get_Item(num3).ZoomLevel - this.keyDefinitions.get_Item(num3 + 1).ZoomLevel;
						if (Math.Abs(num9) > 0.5)
						{
							double num10 = Math.Pow(2.0, num9);
							num4 = (Math.Pow(num10, num4) - 1.0) / (num10 - 1.0);
						}
						FlatMapMode.FlatMapModeViewportDefinition flatMapModeViewportDefinition = this.keyDefinitions.get_Item(this.keyDefinitions.get_Count() - 1);
						flatMapModeViewportDefinition.ZoomLevel = Math.Log(1.0 / BezierHelper.GetSmoothedValue(num4, (num3 - 1 >= 0) ? (1.0 / Math.Pow(2.0, this.keyDefinitions.get_Item(num3 - 1).ZoomLevel)) : double.NaN, 1.0 / Math.Pow(2.0, this.keyDefinitions.get_Item(num3).ZoomLevel), 1.0 / Math.Pow(2.0, this.keyDefinitions.get_Item(num3 + 1).ZoomLevel), (num3 + 2 <= this.keyDefinitions.get_Count() - 1) ? (1.0 / Math.Pow(2.0, this.keyDefinitions.get_Item(num3 + 2).ZoomLevel)) : double.NaN), 2.0);
						flatMapModeViewportDefinition.TopLeftLogicalPoint = new Point(BezierHelper.GetSmoothedValue(num4, (num3 - 1 >= 0) ? this.keyDefinitions.get_Item(num3 - 1).TopLeftLogicalPoint.get_X() : double.NaN, this.keyDefinitions.get_Item(num3).TopLeftLogicalPoint.get_X(), this.keyDefinitions.get_Item(num3 + 1).TopLeftLogicalPoint.get_X(), (num3 + 2 <= this.keyDefinitions.get_Count() - 1) ? this.keyDefinitions.get_Item(num3 + 2).TopLeftLogicalPoint.get_X() : double.NaN), BezierHelper.GetSmoothedValue(num4, (num3 - 1 >= 0) ? this.keyDefinitions.get_Item(num3 - 1).TopLeftLogicalPoint.get_Y() : double.NaN, this.keyDefinitions.get_Item(num3).TopLeftLogicalPoint.get_Y(), this.keyDefinitions.get_Item(num3 + 1).TopLeftLogicalPoint.get_Y(), (num3 + 2 <= this.keyDefinitions.get_Count() - 1) ? this.keyDefinitions.get_Item(num3 + 2).TopLeftLogicalPoint.get_Y() : double.NaN));
						bool flag = this.currentViewportDefinition.ZoomLevel != flatMapModeViewportDefinition.ZoomLevel;
						this.nextKeyZoomLevel = this.keyDefinitions.get_Item(num3 + 1).ZoomLevel;
						this.currentViewportDefinition = flatMapModeViewportDefinition;
						this.OnProjectionChanged(flag ? ProjectionUpdateLevel.Full : ProjectionUpdateLevel.Linear);
						this.animationStoryboard.Begin();
						return;
					}
					num7 += num8;
				}
				goto IL_171;
			}
			this.SnapToTarget();
		}
		private FlatMapMode.FlatMapModeViewportDefinition GetDefinitionByBounds(IList<Point> logicalPoints)
		{
			FlatMapMode.FlatMapModeViewportDefinition result = default(FlatMapMode.FlatMapModeViewportDefinition);
			result.LogicalAreaSizeInScreenSpaceAtLevel1 = this.logicalAreaSizeInScreenSpaceAtLevel1;
			if (logicalPoints.get_Count() > 0)
			{
				Rect rect = new Rect(logicalPoints.get_Item(0), new Size(0.0, 0.0));
				for (int i = 1; i < logicalPoints.get_Count(); i++)
				{
					rect.Union(logicalPoints.get_Item(i));
				}
				Size viewportSize = base.ViewportSize;
				result.ZoomLevel = Math.Min(Math.Log(2.0 * viewportSize.get_Width() / (this.logicalAreaSizeInScreenSpaceAtLevel1.get_Width() * rect.get_Width()), 2.0), Math.Log(2.0 * viewportSize.get_Height() / (this.logicalAreaSizeInScreenSpaceAtLevel1.get_Height() * rect.get_Height()), 2.0));
				result.ZoomLevel = Math.Floor(result.ZoomLevel);
				result.SetTopLeftLogicalPoint(new Point(viewportSize.get_Width() / 2.0, viewportSize.get_Height() / 2.0), new Point(rect.get_X() + rect.get_Width() / 2.0, rect.get_Y() + rect.get_Height() / 2.0));
				return result;
			}
			return result;
		}
		private FlatMapMode.FlatMapModeViewportDefinition ViewToDefinition(GeoCoordinate center, double zoomLevel)
		{
			FlatMapMode.FlatMapModeViewportDefinition result = default(FlatMapMode.FlatMapModeViewportDefinition);
			result.LogicalAreaSizeInScreenSpaceAtLevel1 = this.logicalAreaSizeInScreenSpaceAtLevel1;
			result.ZoomLevel = zoomLevel;
			result.SetTopLeftLogicalPoint(new Point(base.ViewportSize.get_Width() / 2.0, base.ViewportSize.get_Height() / 2.0), this.LocationToLogicalPoint(center));
			return result;
		}
		private void DefinitionToView(FlatMapMode.FlatMapModeViewportDefinition viewportDefinition, out GeoCoordinate center, out double zoomLevel)
		{
			Point logicalPoint = viewportDefinition.ViewportPointToLogicalPoint(new Point(base.ViewportSize.get_Width() / 2.0, base.ViewportSize.get_Height() / 2.0));
			center = this.LogicalPointToLocation(logicalPoint);
			zoomLevel = viewportDefinition.ZoomLevel;
		}
	}
}
